<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Brainfuck</title>
    <link rel="stylesheet" href="./css/index.css">
</head>

<body>
    <div id="LP" class="leftPage">
    </div>
    <div class="rightPage">
        <h2>代码</h2>
        <textarea id="code" class="writeArea" name="code" type="text" autofocus=true></textarea>
        <h2>输入</h2>
        <input id="input" class="writeArea" type="text">
        <button class="start" onclick="runCode()">Run</button>
        <h2>输出</h2>
        <p id="outPut"></p>
    </div>

</body>
<script src="./js/marked.min.js"></script>
<script>

    // 储存文档变量
    docOfBf = "";
    
    xhr = new XMLHttpRequest();
    xhr.open('get','./md/doc.md')
    xhr.send('');
    xhr.onload = function(){
        docOfBf = String(xhr.responseText);
        document.getElementById('LP').innerHTML = marked(docOfBf);;
    }

    function init(){

    }

    function showDoc()
    {
        document.getElementById('LP').innerHTML = marked(docOfBf);;
    }


    function getMatchingBra(code) {
        // 解析code，去除换行符
        var stack = [];
        var bra = [];
        for (var i = 0; i < code.length; i++) {
            bra.push(-1);
        }
        for (var i = 0; i < code.length; i++) {
            if (code[i] === '[') {
                stack.push(i);
            } else if (code[i] === ']') {
                bra[i] = stack.pop();
                bra[bra[i]] = i;
            }
        }
        return bra;
    }

    function brainfuck(code, input) {
        var inputPos = 0;
        var commandPos = 0;
        var pointerPos = 0;
        var bytes = [0];
        var command = "" //Record command
        var output = "";
        var matching = getMatchingBra(code);

        while (commandPos < code.length) {
            switch (code[commandPos]) {
                case '>': {
                    pointerPos++;
                    if (undefined === bytes[pointerPos]) {
                        bytes.push(0);
                    }
                    command += '>'
                    break;
                }
                case '<': {
                    pointerPos--;
                    if (0 > pointerPos) {
                        bytes.unshift(0);
                        pointerPos = 0;
                    }
                    command += '<'
                    break;
                }
                case '+': {
                    bytes[pointerPos] = (bytes[pointerPos] + 1) % 256;
                    command += '+'
                    break;
                }
                case '-': {
                    bytes[pointerPos]--;
                    if (bytes[pointerPos] < 0) bytes[pointerPos] = 0;
                    command += '-'
                    break;
                }
                case '.': {
                    output += String.fromCharCode(bytes[pointerPos]);
                    command += '.'
                    break;
                }
                case ',': {
                    var temp = input.charCodeAt(inputPos++);
                    bytes[pointerPos] = temp;
                    command += ','
                    break;
                }
                case '[': {
                    if (!bytes[pointerPos]) {
                        commandPos = matching[commandPos];
                    }
                    break;
                }
                case ']': {
                    if (bytes[pointerPos]) {
                        commandPos = matching[commandPos];
                    }
                    break;
                }
            }
            commandPos++;
        }

        return [output, command];
    }

    function runCode() {
        var input = document.getElementById("input").value;
        var code = document.getElementById("code").value;
        var output = brainfuck(code, input);
        var command = output[1]
        document.getElementById("outPut").innerText = output[0];
    }

    init();
    showDoc();
</script>

</html>